import { Controller } from 'egg';
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const moment = require('moment')
const allowParams = require('../api_allow_params.js');

export default class FontAPIController extends Controller {

  /**
   * @api {get} fontapi/:params/list 获取前台导航菜单列表(前台)
   *  
   * @apiName list
   * @apiGroup Fontapi
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */
  public async list(ctx) {
    const { params: param } = ctx.params;
    const length = await this.app.redis.llen(`database-${param}-api`);
    const originList = await this.app.redis.lrange(`database-${param}-api`, 0, length - 1);
    let list = originList.map(item => {
      let parseItem = JSON.parse(item);
      return {
        value: parseItem.value,
        name: parseItem.name
      }
    });
    ctx.response.body = {
      code: 200,
      data: list,
      count: length,
      status: '成功'
    }
  }

  /**
   * @api {get} fontapi/:params/articleList 获取前台导航菜单文章列表
   *  
   * @apiName articleList
   * @apiGroup Fontapi
   * @apiParam {String} value 字段标识
   * @apiParam {String} [pageNo] 页码
   * @apiParam {String} [pageSize] 每页显示数
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */
  public async articleList(ctx) {
    const { params: param } = ctx.params;
    let sortQueryList = []; // 存储排序数据
    let filterQueryList = []; // 存储过滤后的数据
    const { pageNo = 1, pageSize = 10, value } = ctx.request.query;
    let { limit, offset } = ctx.helper.changePage(pageNo, pageSize);
    try {
      if (!allowParams.includes(param)) {
        throw ctx.helper.getErrorMsg(207);
      }
      const length = await this.app.redis.llen(`database-${param}-api`);
      const originList = await this.app.redis.lrange(`database-${param}-api`, 0, length - 1);
      let filterList = originList.filter(item => {
        let parse_item = JSON.parse(item);
        if (parse_item.value === value) {
          return item;
        }
      });
      let { type, permissions } = JSON.parse(filterList[0]) || {};
      let queryList: any = {
        count: 0,
        rows: []
      };
      if (type === 'tag') {
        let permissionArray = permissions.split(',');
        queryList = await ctx.model.Article.findAndCountAll({
          attributes: ['id', 'title', 'author', 'summary', 'content', 'preview', 'articleId', 'categoryId', 'subCategoryId', 'tags', 'createdAt', 'toTop'],
          where: {
            tags: {
              [Op.regexp]: permissionArray
            },
            status: 'publish'
          },
          limit: limit,
          offset: offset
        });

      } else if (type === 'category') {

        let permissionArray = permissions.split(',');
        let categoryObject: any = {};
        let cacheSaveCategoryArray: any = []; // 缓存写入的category

        permissionArray.forEach(item => {
          let splitArray = item.split('-');
          if (!cacheSaveCategoryArray.includes(`${splitArray[0]}`)) {
            cacheSaveCategoryArray.push(`${splitArray[0]}`)
            categoryObject[`${splitArray[0]}`] = []
          }
          categoryObject[`${splitArray[0]}`].push(`${splitArray[1]}`)
        });
        // 转换categoryObject格式
        let categoryFormat: any = [];
        for (let key in categoryObject) {

          let item = {
            category: parseInt(key),
            subCategory: categoryObject[key].map(val => parseInt(val))
          }
          categoryFormat.push(item)
        }
        // tslint:disable-next-line:prefer-for-of
        for (let i = 0; i < categoryFormat.length; i++) {
          let tempList: any = await ctx.model.Article.findAndCountAll({
            attributes: ['id', 'title', 'author', 'content', 'preview', 'articleId', 'categoryId', 'subCategoryId', 'summary', 'tags', 'createdAt', 'toTop'],
            where: {
              categoryId: categoryFormat[i].category,
              subCategoryId: {
                [Op.or]: categoryFormat[i].subCategory
              },
              status: 'publish'
            }
          });
          queryList.count += tempList.count;
          queryList.rows.push(...tempList.rows);
        }
        // 时间排序(快速排序)
        sortQueryList = queryList.rows.sort((aItem, bItem) => {
          return moment(aItem.dataValues.createdAt).diff(moment(bItem.dataValues.createdAt))
        })

        // 过滤需要显示的数据数
        filterQueryList = sortQueryList.slice(offset, limit)
        queryList.rows = filterQueryList
      }

      // 静态添加管理员头像
      queryList.rows.forEach(item => {
        item.dataValues.protrait = 'static/images/internal/admin.jpg';
      });
      ctx.response.body = {
        code: 200,
        count: queryList.count,
        data: queryList.rows,
        status: '成功'
      }
    } catch (error_info) {
      ctx.response.body = error_info;
    }

  }

  /**
   * @api {get} fontapi/:params/adminList 获取前台导航菜单列表(后台)
   *  
   * @apiName adminList
   * @apiGroup Fontapi
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */
  public async adminList(ctx) {
    const { params: param } = ctx.params;

    const originList = await this.app.redis.lrange(`database-${param}-api`, 0, -1);
    let list = originList.map(item => {
      return JSON.parse(item);
    });
    const length = await this.app.redis.llen(`database-${param}-api`);
    ctx.response.body = {
      code: 200,
      data: list,
      count: length,
      status: '成功'
    }
  }

  /**
   * @api {post} fontapi/:params/adminUpdate 更新前台导航菜单列表(后台)
   *
   * @apiName adminUpdate
   * @apiGroup Fontapi
   * @apiParam {Array} list 需要更新的数据
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */

  public async adminUpdate(ctx) {
    const { params: param } = ctx.params;
    const { list } = ctx.request.body;
    await this.app.redis.ltrim(`database-${param}-api`, 1, 0)
    await this.app.redis.rpush(`database-${param}-api`, ...list.map(item => JSON.stringify(item)));
    ctx.response.body = {
      code: 200,
      status: '成功'
    }
  }

  /**
   * @api {post} fontapi/:params/add 添加前台导航菜单字段
   *  
   * @apiName add
   * @apiGroup Fontapi
   * @apiParam {String} value 字段标识
   * @apiParam {String} name 字段显示名
   * @apiParam {String} type 绑定类型（tag-标签 category-分类 custom-自定义）
   * @apiParam {String} permissions 访问权限
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */
  public async add(ctx) {
    const { params: param } = ctx.params;
    let { name, value, type } = ctx.request.body;
    try {
      if (!allowParams.includes(param)) {
        throw ctx.helper.getErrorMsg(207);
      }
      if (!type || type === '') {
        throw ctx.helper.getErrorMsg(207);
      }
      // 传入内容检测
      const length = await this.app.redis.llen(`database-${param}-api`);
      const getList = await this.app.redis.lrange(`database-${param}-api`, 0, length - 1);
      let getOrignList = getList.map(item => {
        return JSON.parse(item);
      });
      getOrignList.forEach(item => {
        if (item.value === value || item.name === name) {
          throw ctx.helper.getErrorMsg(215);
        }
      });

      await this.app.redis.rpush(`database-${param}-api`, JSON.stringify(ctx.request.body));
      ctx.response.body = {
        code: 200,
        status: '成功'
      }
    } catch (error_info) {
      ctx.response.body = error_info;
    }

  }

  /**
   * @api {post} fontapi/:params/edit 编辑前台导航菜单
   *  
   * @apiName edit
   * @apiGroup Fontapi
   * @apiParam {String} value 字段标识
   * @apiParam {String} name 字段显示名
   * @apiParam {String} type 绑定类型（tag-标签 category-分类 custom-自定义）
   * @apiParam {String} permissions 访问权限
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过
   *
   */
  public async edit(ctx) {
    const { params: param } = ctx.params;
    let { value, type } = ctx.request.body;
    try {
      if (!allowParams.includes(param)) {
        throw ctx.helper.getErrorMsg(207);
      }
      if (!type || type === '') {
        throw ctx.helper.getErrorMsg(207);
      }
      const length = await this.app.redis.llen(`database-${param}-api`);
      const getList = await this.app.redis.lrange(`database-${param}-api`, 0, length - 1);
      await this.app.redis.del(`database-${param}-api`);
      let getOrignList = getList.map(item => {
        return JSON.parse(item);
      });
      let newMapList = getOrignList.map(item => {
        if (item.value !== value) {
          return item;
        } else {
          return ctx.request.body;
        }
      });

      for (let item of newMapList) {
        await this.app.redis.rpush(`database-${param}-api`, JSON.stringify(item));
      }
      ctx.response.body = {
        code: 200,
        status: '成功'
      }
    } catch (error_info) {
      ctx.response.body = error_info;
    }

  }

  /**
   * @api {get} fontapi/:params/delete/:filedValue 删除前台导航菜单字段
   *  
   * @apiName delete
   * @apiGroup Fontapi
   * @apiHeaderExample {json} headers:
   *     {
   *       "token": "admin_token"
   *     }
   *
   * @apiDescription :params代表的是接口的参数，必须在全局配置中被允许才能通过,:filedValue 需要删除的字段value
   *
   */
  public async delete(ctx) {
    try {
      const { params: param, filedValue } = ctx.params;
      const length = await this.app.redis.llen(`database-${param}-api`);
      const getList = await this.app.redis.lrange(`database-${param}-api`, 0, length - 1);
      let getOrignList = getList.map(item => {
        return JSON.parse(item);
      });
      await this.app.redis.del(`database-${param}-api`);
      let filterArray = getOrignList.filter(item => {
        return item.value !== filedValue;
      });
      filterArray.forEach(async item => {
        await this.app.redis.rpush(`database-${param}-api`, JSON.stringify(item));
      });
      ctx.response.body = {
        code: 200,
        status: '成功'
      }
    } catch (error_info) {
      ctx.response.body = error_info;
    }
  }
}
